package com.springboot.killingsystem.service;

import com.springboot.killingsystem.dao.SecondKillingUserDao;
import com.springboot.killingsystem.domain.SecondKillingUser;
import com.springboot.killingsystem.exception.GlobalException;
import com.springboot.killingsystem.redis.RedisService;
import com.springboot.killingsystem.redis.SecondKillingUserKey;
import com.springboot.killingsystem.result.CodeMsg;
import com.springboot.killingsystem.util.Constant;
import com.springboot.killingsystem.util.MD5Util;
import com.springboot.killingsystem.util.UUIDUtil;
import com.springboot.killingsystem.vo.LoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

@Service
@Slf4j
public class SecondKillingUserService {

    @Autowired
    SecondKillingUserDao systemUserDao;

    @Autowired
    RedisService redisService;

    public SecondKillingUser getById(long id) {
        // 对象缓存
        SecondKillingUser user = redisService.get(SecondKillingUserKey.getById, Constant.DEFAULT_KEY + id, SecondKillingUser.class);
        if (user != null) {
            return user;
        }
        // 取数据库
        user = systemUserDao.getById(id);
        if (user != null) {
            redisService.set(SecondKillingUserKey.getById, Constant.DEFAULT_KEY + id, user);
        }
        return user;
    }

    public boolean updatePassword(
            String token,
            long id,
            String formPassword
    ) {
        // 取user
        SecondKillingUser user = getById(id);
        if (user == null) {
            throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
        }

        // 更新数据库
        SecondKillingUser userNew = new SecondKillingUser();
        userNew.setId(id);
        userNew.setPassword(MD5Util.formPassToDBPass(formPassword, user.getSalt()));
        systemUserDao.update(userNew);

        // 清除缓存
        redisService.delete(SecondKillingUserKey.getById, Constant.DEFAULT_KEY+id);

        // 更新缓存
        user.setPassword(userNew.getPassword());
        redisService.set(SecondKillingUserKey.token, token, user);

        return true;
    }

    public String login(HttpServletResponse response, LoginVo loginVo) {
        if (loginVo == null) {
            throw new GlobalException(CodeMsg.SERVER_ERROR);
        }
        String mobile = loginVo.getMobile();
        String formPass = loginVo.getPassword();
        // 判断手机号是否存在
        SecondKillingUser user = getById(Long.parseLong(mobile));
        if (user == null) {
            throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
        }
        // 验证密码
        String dbPass = user.getPassword();
        String saltDB = user.getSalt();
        String invalidatePass = MD5Util.formPassToDBPass(formPass, saltDB);
        if (!invalidatePass.equals(dbPass)) {
            throw new GlobalException(CodeMsg.PASSWORD_ERROR);
        }

        // 生成token并将其作为key加入redis
        String token = UUIDUtil.uuid();
        // 生成cookie
        addCookie(user, token, response);
        return token;
    }

    public SecondKillingUser getByToken(String token, HttpServletResponse response) {
        if (StringUtils.isEmpty(token)) {
            return null;
        }

        SecondKillingUser user = redisService.get(SecondKillingUserKey.token, token, SecondKillingUser.class);
        if (user != null) {
            // 延长有效期
            addCookie(user, token, response);
        }

        return user;
    }

    public void addCookie(SecondKillingUser user, String token, HttpServletResponse response) {
        // 生成token并将其作为key加入redis
        redisService.set(SecondKillingUserKey.token, token, user);
        Cookie cookie = new Cookie(Constant.COOKIE_NAME_TOKEN, token);
        // 将Cookie的过期时间设置为token的过期时间，这样保证token过期时客户端的Cookie也失效
        cookie.setMaxAge(SecondKillingUserKey.token.expireSecond());
        // 设置为"/"使得Cookie可以在同一个应用服务器共享
        cookie.setPath("/");
        response.addCookie(cookie);
    }
}
